/*
 * Copyright (c) 2010 by Aleksey Zhukov
 * Licensed under the Apache License, Version 2.0 (the "License")
 */

package ru.listfunc4j;

import org.junit.Test;

import java.util.Arrays;
import java.util.List;

import static org.junit.Assert.assertTrue;
import static ru.listfunc4j.ListFunction.forEach;

/**
 * User: J0k3r
 * Date: 06.11.2010
 * Time: 21:18:33
 */
public class ListFunctionTest {
    @Test
    public void testOf() throws Exception {
        List < SimpleBean > myList = Arrays.asList(new SimpleBean("1"), new SimpleBean("2"), new SimpleBean("3"));
        forEach(myList).of(SimpleBean.class).setS("New S");
        for (SimpleBean simpleBean : myList)
            assertTrue("Simple bean getS() should return 'New S' value", simpleBean.getS().equals("New S"));
    }

    @Test
    public void testFinalVars() throws Exception {
        List < Long > myList = Arrays.asList(1L, 2L, 3L);
        final long x = 100L;
        Long result = forEach(myList)
                .aggregate(new Aggregator<Long, Long>(0L) {{ _ += x + $; }})
                .uniqueResult();
        assertTrue("Result must be = 306L", result.equals(306L));
    }

    @Test
    public void testLambda() throws Exception {
        List < Long > myList = Arrays.asList(1L, 2L, 3L);
        List<Object> resultList = forEach(myList).
                add(new Lambda<Long, Integer>() {{ _ = $.intValue(); }}).
                toList();
        assertTrue("List size must be = 3 ", resultList.size() == 3);
        for (Object o : resultList)
            assertTrue("List items must be instanceof Integer ", o instanceof Integer);
    }

    @Test
    public void testFilter() throws Exception {
        List < Long > myList = Arrays.asList(1L, 2L, 3L);
        List<Long> resultList = forEach(myList)
                .filter(new Filter<Long>() {{ _ = $.equals(2L); }})
                .toList();
        assertTrue("Result list size should be = 1", resultList.size() == 1);
        assertTrue("Result should consist of 2L", resultList.get(0).equals(2L));
    }

    @Test
    public void testConveyor() throws Exception {
        List < Long > myList = Arrays.asList(1L, 2L, 3L);
        List retustList = forEach(myList)
                .add(new Lambda<Long, Long>() {{ _ = $ + 1; }})
                .add(new Lambda<Long, Integer>() {{ _ = $.intValue(); }})
                .toList();
        for (int nI = 0; nI < retustList.size(); ++nI) {
            assertTrue("List items must be instanceof Integer", retustList.get(nI) instanceof Integer);
            assertTrue("Math operation failed", (Integer) retustList.get(nI) == (myList.get(nI) + 1));
        }
    }

    @Test
    public void testAggregator() throws Exception {
        List < Long > myList = Arrays.asList(1L, 2L, 3L);
        assertTrue("Sum should be = 6", forEach(myList)
                .aggregate(new Aggregator<Long, Long>(0L) {{ _ += $; }})
                .uniqueResult().equals(6L));
    }

    @Test
    public void testForEach() throws Exception {
        List < Long > myList = Arrays.asList(0L, 1L, 2L, 3L);
        final int x = 100;
        forEach(myList)
                .add(new Lambda<Long, Integer>() {{ _ = $.intValue(); }})
                .add(new Lambda() {{ System.out.println("test " + (_ = $)); }})
                .filter(new Filter<Integer>() {{ _ = ($ > 0); }})
                .update(new Updater<Integer>() {{ System.out.println("more than 0: " + $); }})
                .aggregate(new Aggregator<Integer, Integer>(0){{ _ += $; }})
                .update(new Updater() {{ System.out.println("Sum = " + $); }})
                .add(new Lambda<Integer, Integer>() {{ System.out.println("With final " + (_ = $ + x));}});
    }

    @Test
    public void testSort() {
        List < Long > myList = Arrays.asList(0L, 1L, 0L, 3L, 5L, 2L, 3L);
        List<Long> result = forEach(myList).
                sort(new Sorter<Long>() {{ _ = $1.compareTo($2); }}).
                update(new Updater<Long>() {{ System.out.println($); }}).toList();
        assertTrue("Wrong order on 0", result.get(0).equals(0L));
        assertTrue("Wrong order on 1", result.get(1).equals(0L));
        assertTrue("Wrong order on 2", result.get(2).equals(1L));
        assertTrue("Wrong order on 3", result.get(3).equals(2L));
        assertTrue("Wrong order on 4", result.get(4).equals(3L));
        assertTrue("Wrong order on 5", result.get(5).equals(3L));
        assertTrue("Wrong order on 6", result.get(6).equals(5L));

    }
}